#include <cmath> // for fabs
#include <cstdlib> // for strtod
-#include <QtCore/QtGlobal> // for foreach
+#include <QtCore/QList> // for QList
+#include <QtCore/QtGlobal> // for qAsConst, QAddConst<>::Type
#include "defs.h"
#include "filterdefs.h"
-#include "grtcirc.h" // for RAD, gcdist, radtomiles
+#include "grtcirc.h" // for RAD, gcdist, radtometers
#include "position.h"
#if FILTERS_ENABLED
double PositionFilter::gc_distance(double lat1, double lon1, double lat2, double lon2)
{
- return gcdist(
- RAD(lat1),
- RAD(lon1),
- RAD(lat2),
- RAD(lon2)
- );
+ return radtometers(gcdist(
+ RAD(lat1),
+ RAD(lon1),
+ RAD(lat2),
+ RAD(lon2)
+ ));
}
/* tear through a waypoint queue, processing points by distance */
-void PositionFilter::position_runqueue(WaypointList* waypt_list, int nelems, int qtype)
+void PositionFilter::position_runqueue(WaypointList* waypt_list, int qtype)
{
- double dist, diff_time;
- int i = 0, anyitem;
+ QList<WptRecord> qlist;
- Waypoint** comp = (Waypoint**) xcalloc(nelems, sizeof(*comp));
- int* qlist = (int*) xcalloc(nelems, sizeof(*qlist));
-
- foreach (Waypoint* waypointp, *waypt_list) {
- comp[i] = waypointp;
- qlist[i] = 0;
- i++;
+ for (const auto waypointp : qAsConst(*waypt_list)) {
+ qlist.append(WptRecord(waypointp));
}
+ int nelems = qlist.size();
- for (i = 0 ; i < nelems ; i++) {
- anyitem = 0;
-
- if (!qlist[i]) {
- for (int j = i + 1 ; j < nelems ; j++) {
- if (!qlist[j]) {
- dist = gc_distance(comp[j]->latitude,
- comp[j]->longitude,
- comp[i]->latitude,
- comp[i]->longitude);
+ for (int i = 0 ; i < nelems ; ++i) {
+ bool something_deleted = false;
- /* convert radians to integer feet */
- dist = (int)(5280*radtomiles(dist));
- diff_time = fabs(waypt_time(comp[i]) - waypt_time(comp[j]));
+ if (!qlist.at(i).deleted) {
+ for (int j = i + 1 ; j < nelems ; ++j) {
+ if (!qlist.at(j).deleted) {
+ double dist = gc_distance(qlist.at(j).wpt->latitude,
+ qlist.at(j).wpt->longitude,
+ qlist.at(i).wpt->latitude,
+ qlist.at(i).wpt->longitude);
if (dist <= pos_dist) {
- if (check_time && diff_time >= max_diff_time) {
- continue;
+ if (check_time) {
+ double diff_time = fabs(waypt_time(qlist.at(i).wpt) - waypt_time(qlist.at(j).wpt));
+ if (diff_time >= max_diff_time) {
+ continue;
+ }
}
- qlist[j] = 1;
+ qlist[j].deleted = true;
switch (qtype) {
case wptdata:
- waypt_del(comp[j]);
- delete comp[j];
+ waypt_del(qlist.at(j).wpt);
+ delete qlist.at(j).wpt;
break;
case trkdata:
- track_del_wpt(cur_rte, comp[j]);
- delete comp[j];
+ track_del_wpt(cur_rte, qlist.at(j).wpt);
+ delete qlist.at(j).wpt;
break;
case rtedata:
- route_del_wpt(cur_rte, comp[j]);
- delete comp[j];
+ route_del_wpt(cur_rte, qlist.at(j).wpt);
+ delete qlist.at(j).wpt;
break;
default:
break;
}
- anyitem = 1;
+ something_deleted = true;
+ } else {
+ // Unlike waypoints, routes and tracks are ordered paths.
+ // Don't eliminate points from the return path when the
+ // route or track loops back on itself.
+ if ((qtype == trkdata) || (qtype == rtedata)) {
+ break;
+ }
}
}
}
- if (anyitem && !!purge_duplicates) {
+ if (something_deleted && (purge_duplicates != nullptr)) {
switch (qtype) {
case wptdata:
- waypt_del(comp[i]);
- delete comp[i];
+ waypt_del(qlist.at(i).wpt);
+ delete qlist.at(i).wpt;
break;
case trkdata:
- track_del_wpt(cur_rte, comp[i]);
- delete comp[i];
+ track_del_wpt(cur_rte, qlist.at(i).wpt);
+ delete qlist.at(i).wpt;
break;
case rtedata:
- route_del_wpt(cur_rte, comp[i]);
- delete comp[i];
+ route_del_wpt(cur_rte, qlist.at(i).wpt);
+ delete qlist.at(i).wpt;
break;
default:
break;
}
}
- if (comp) {
- xfree(comp);
- }
-
- if (qlist) {
- xfree(qlist);
- }
}
void PositionFilter::position_process_any_route(const route_head* rh, int type)
{
- int i = rh->rte_waypt_ct;
-
- if (i) {
+ if (rh->rte_waypt_ct != 0) {
cur_rte = const_cast<route_head*>(rh);
- position_runqueue(&cur_rte->waypoint_list, i, type);
+ position_runqueue(&cur_rte->waypoint_list, type);
cur_rte = nullptr;
}
-
}
void PositionFilter::position_process_rte(const route_head* rh)
RteHdFunctor<PositionFilter> position_process_rte_f(this, &PositionFilter::position_process_rte);
RteHdFunctor<PositionFilter> position_process_trk_f(this, &PositionFilter::position_process_trk);
- int i = waypt_count();
-
- if (i) {
- position_runqueue(global_waypoint_list, i, wptdata);
+ if (waypt_count() != 0) {
+ position_runqueue(global_waypoint_list, wptdata);
}
route_disp_all(position_process_rte_f, nullptr, nullptr);
{
char* fm;
- pos_dist = 0;
- max_diff_time = 0;
- check_time = 0;
+ pos_dist = 0.0;
+ max_diff_time = 0.0;
+ check_time = false;
- if (distopt) {
+ if (distopt != nullptr) {
pos_dist = strtod(distopt, &fm);
- if ((*fm == 'm') || (*fm == 'M')) {
- /* distance is meters */
- pos_dist *= 3.2802;
+ if (!((*fm == 'm') || (*fm == 'M'))) {
+ /* distance is feet */
+ pos_dist = FEET_TO_METERS(pos_dist);
}
}
- if (timeopt) {
- check_time = 1;
+ if (timeopt != nullptr) {
+ check_time = true;
max_diff_time = strtod(timeopt, &fm);
}
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
+ <time>2019-07-06T15:46:06.559Z</time>
+ <bounds minlat="40.008761985" minlon="-105.207110341" maxlat="40.009199023" maxlon="-105.205790238"/>
+ <trk>
+ <name>Untitled Path</name>
+ <trkseg>
+ <trkpt lat="40.009054849" lon="-105.206004844"/>
+ <trkpt lat="40.009031242" lon="-105.206070277"/>
+ <trkpt lat="40.009003650" lon="-105.206144881"/>
+ <trkpt lat="40.008976867" lon="-105.206225622"/>
+ <trkpt lat="40.008941848" lon="-105.206316939"/>
+ <trkpt lat="40.008909765" lon="-105.206391276"/>
+ <trkpt lat="40.008883566" lon="-105.206475630"/>
+ <trkpt lat="40.008850838" lon="-105.206558580"/>
+ <trkpt lat="40.008820497" lon="-105.206640987"/>
+ <trkpt lat="40.008794757" lon="-105.206702329"/>
+ <trkpt lat="40.008761985" lon="-105.206788064"/>
+ <trkpt lat="40.008805279" lon="-105.206815339"/>
+ <trkpt lat="40.008859906" lon="-105.206845941"/>
+ <trkpt lat="40.008905939" lon="-105.206879224"/>
+ <trkpt lat="40.008945815" lon="-105.206917917"/>
+ <trkpt lat="40.008989205" lon="-105.206964005"/>
+ <trkpt lat="40.009030426" lon="-105.207004804"/>
+ <trkpt lat="40.009073806" lon="-105.207053719"/>
+ <trkpt lat="40.009121469" lon="-105.207110341"/>
+ <trkpt lat="40.009164218" lon="-105.207035615"/>
+ <trkpt lat="40.009118062" lon="-105.206978787"/>
+ <trkpt lat="40.009072029" lon="-105.206928441"/>
+ <trkpt lat="40.009030957" lon="-105.206889679"/>
+ <trkpt lat="40.008992964" lon="-105.206852408"/>
+ <trkpt lat="40.008921748" lon="-105.206773246"/>
+ <trkpt lat="40.008886986" lon="-105.206698496"/>
+ <trkpt lat="40.008905642" lon="-105.206619702"/>
+ <trkpt lat="40.008927841" lon="-105.206560216"/>
+ <trkpt lat="40.008951025" lon="-105.206500804"/>
+ <trkpt lat="40.008974216" lon="-105.206446800"/>
+ <trkpt lat="40.008992342" lon="-105.206380934"/>
+ <trkpt lat="40.009020531" lon="-105.206315106"/>
+ <trkpt lat="40.009042694" lon="-105.206261158"/>
+ <trkpt lat="40.009064774" lon="-105.206192784"/>
+ <trkpt lat="40.009085925" lon="-105.206134925"/>
+ <trkpt lat="40.009109989" lon="-105.206066651"/>
+ <trkpt lat="40.009137114" lon="-105.205995744"/>
+ <trkpt lat="40.009161137" lon="-105.205930216"/>
+ <trkpt lat="40.009181255" lon="-105.205863237"/>
+ <trkpt lat="40.009199023" lon="-105.205790238"/>
+ </trkseg>
+ </trk>
+</gpx>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<gpx version="1.0" creator="GPSBabel - http://www.gpsbabel.org" xmlns="http://www.topografix.com/GPX/1/0">
+ <time>1970-01-01T00:00:00Z</time>
+ <bounds minlat="40.008761985" minlon="-105.207110341" maxlat="40.009181255" maxlon="-105.205863237"/>
+ <trk>
+ <name>Untitled Path</name>
+ <trkseg>
+ <trkpt lat="40.009054849" lon="-105.206004844"/>
+ <trkpt lat="40.009003650" lon="-105.206144881"/>
+ <trkpt lat="40.008941848" lon="-105.206316939"/>
+ <trkpt lat="40.008883566" lon="-105.206475630"/>
+ <trkpt lat="40.008820497" lon="-105.206640987"/>
+ <trkpt lat="40.008761985" lon="-105.206788064"/>
+ <trkpt lat="40.008905939" lon="-105.206879224"/>
+ <trkpt lat="40.009030426" lon="-105.207004804"/>
+ <trkpt lat="40.009121469" lon="-105.207110341"/>
+ <trkpt lat="40.009072029" lon="-105.206928441"/>
+ <trkpt lat="40.008921748" lon="-105.206773246"/>
+ <trkpt lat="40.008905642" lon="-105.206619702"/>
+ <trkpt lat="40.008974216" lon="-105.206446800"/>
+ <trkpt lat="40.009020531" lon="-105.206315106"/>
+ <trkpt lat="40.009085925" lon="-105.206134925"/>
+ <trkpt lat="40.009137114" lon="-105.205995744"/>
+ <trkpt lat="40.009181255" lon="-105.205863237"/>
+ </trkseg>
+ </trk>
+</gpx>